using Sage.CloudStorage.Qiniu.Auth;
using Sage.CloudStorage.Qiniu.Config;
using Sage.CloudStorage.Qiniu.Models;
using Sage.Http.Core;

namespace Sage.CloudStorage.Qiniu.Cdn
{
    /// <summary>
    /// CDN管理器 - 提供CDN相关功能
    /// </summary>
    /// <remarks>
    /// 创建CDN管理器实例
    /// </remarks>
    /// <param name="httpManager">HTTP请求管理器</param>
    /// <param name="key">七牛云密钥信息</param>
    /// <param name="config">七牛云配置</param>
    public class CdnManager(HttpRequestManager httpManager, QiniuKey key, QiniuConfig config)
    {
        private readonly HttpRequestManager _httpManager = httpManager ?? throw new ArgumentNullException(nameof(httpManager));
        private readonly QiniuKey _key = key ?? throw new ArgumentNullException(nameof(key));
        private readonly QiniuConfig _config = config ?? throw new ArgumentNullException(nameof(config));

        /// <summary>
        /// 刷新文件
        /// </summary>
        /// <param name="urls">文件URL列表</param>
        /// <returns>刷新结果</returns>
        public async Task<CdnRefreshResult> RefreshUrlsAsync(IEnumerable<string> urls)
        {
            ArgumentNullException.ThrowIfNull(urls);

            var urlList = urls.ToList();
            if (urlList.Count == 0)
                throw new ArgumentException("URL列表不能为空", nameof(urls));

            if (urlList.Count > 100)
                throw new ArgumentException("单次刷新URL数量不能超过100个", nameof(urls));

            // 构建请求体
            var requestBody = new CdnUrlRefreshRequest { Urls = urlList };

            // 发送请求
            string url = $"{_config.GetCdnHost()}/v2/tune/flux";
            var authProvider = new QiniuAuthProvider(_key, QiniuAuthType.ManageApiV2);
            var result = await _httpManager.CreateRequest(HttpMethod.Post, url)
                .WithAuthentication(authProvider)
                .WithJsonContent(requestBody, QiniuJsonSerializerContext.Default.CdnUrlRefreshRequest)
                .SendAsJsonAsync(QiniuJsonSerializerContext.Default.CdnRefreshResult); //CdnRefreshResult

            return result ?? new CdnRefreshResult();
        }

        /// <summary>
        /// 刷新目录
        /// </summary>
        /// <param name="dirs">目录URL列表</param>
        /// <returns>刷新结果</returns>
        public async Task<CdnRefreshResult> RefreshDirsAsync(IEnumerable<string> dirs)
        {
            ArgumentNullException.ThrowIfNull(dirs);

            var dirList = dirs.ToList();
            if (dirList.Count == 0)
                throw new ArgumentException("目录列表不能为空", nameof(dirs));

            if (dirList.Count > 10)
                throw new ArgumentException("单次刷新目录数量不能超过10个", nameof(dirs));

            // 构建请求体
            var requestBody = new CdnDirRefreshRequest { Dirs = dirList };

            // 发送请求
            string url = $"{_config.GetCdnHost()}/v2/tune/refresh";
            var authProvider = new QiniuAuthProvider(_key, QiniuAuthType.ManageApiV2);
            var result = await _httpManager.CreateRequest(HttpMethod.Post, url)
                .WithAuthentication(authProvider)
                .WithJsonContent(requestBody, QiniuJsonSerializerContext.Default.CdnDirRefreshRequest)
                .SendAsJsonAsync(QiniuJsonSerializerContext.Default.CdnRefreshResult);

            return result ?? new CdnRefreshResult();
        }

        /// <summary>
        /// 预取文件
        /// </summary>
        /// <param name="urls">文件URL列表</param>
        /// <returns>预取结果</returns>
        public async Task<CdnPrefetchResult> PrefetchUrlsAsync(IEnumerable<string> urls)
        {
            ArgumentNullException.ThrowIfNull(urls);

            var urlList = urls.ToList();
            if (urlList.Count == 0)
                throw new ArgumentException("URL列表不能为空", nameof(urls));

            if (urlList.Count > 100)
                throw new ArgumentException("单次预取URL数量不能超过100个", nameof(urls));

            // 构建请求体
            var requestBody = new CdnPrefetchRequest { Urls = urlList };

            // 发送请求
            string url = $"{_config.GetCdnHost()}/v2/tune/prefetch";
            var authProvider = new QiniuAuthProvider(_key, QiniuAuthType.ManageApiV2);
            var result = await _httpManager.CreateRequest(HttpMethod.Post, url)
                .WithAuthentication(authProvider)
                .WithJsonContent(requestBody, QiniuJsonSerializerContext.Default.CdnPrefetchRequest)
                .SendAsJsonAsync(QiniuJsonSerializerContext.Default.CdnPrefetchResult);

            return result ?? new CdnPrefetchResult();
        }

        /// <summary>
        /// 获取带宽数据
        /// </summary>
        /// <param name="domains">域名列表</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="granularity">时间粒度（5min、hour、day）</param>
        /// <returns>带宽数据</returns>
        public async Task<CdnBandwidthResult> GetBandwidthDataAsync(
            IEnumerable<string> domains,
            DateTime startTime,
            DateTime endTime,
            string granularity = "hour")
        {
            if (domains == null || !domains.Any())
                throw new ArgumentNullException(nameof(domains));

            if (endTime <= startTime)
                throw new ArgumentException("结束时间必须大于开始时间");

            // 构建请求体
            var requestBody = new CdnBandwidthRequest
            {
                Domains = string.Join(";", domains),
                StartDate = startTime.ToString("yyyy-MM-dd"),
                EndDate = endTime.ToString("yyyy-MM-dd"),
                Granularity = granularity
            };

            // 发送请求
            string url = $"{_config.GetCdnHost()}/v2/tune/bandwidth";
            var authProvider = new QiniuAuthProvider(_key, QiniuAuthType.ManageApiV2);
            var result = await _httpManager.CreateRequest(HttpMethod.Post, url)
                .WithAuthentication(authProvider)
                .WithJsonContent(requestBody, QiniuJsonSerializerContext.Default.CdnBandwidthRequest)
                .SendAsJsonAsync(QiniuJsonSerializerContext.Default.CdnBandwidthResult);

            return result ?? new CdnBandwidthResult();
        }

        /// <summary>
        /// 获取CDN日志下载链接
        /// </summary>
        /// <param name="domains">域名列表</param>
        /// <param name="logDate">日志日期</param>
        /// <returns>日志下载链接</returns>
        public async Task<CdnLogListResult> GetCdnLogsAsync(IEnumerable<string> domains, DateTime logDate)
        {
            if (domains == null || !domains.Any())
                throw new ArgumentNullException(nameof(domains));

            // 构建请求体
            var requestBody = new CdnLogListRequest
            {
                Day = logDate.ToString("yyyy-MM-dd"),
                Domains = string.Join(";", domains)
            };

            // 发送请求
            string url = $"{_config.GetCdnHost()}/v2/tune/log/list";
            var authProvider = new QiniuAuthProvider(_key, QiniuAuthType.ManageApiV2);
            var result = await _httpManager.CreateRequest(HttpMethod.Post, url)
                .WithAuthentication(authProvider)
                .WithJsonContent(requestBody, QiniuJsonSerializerContext.Default.CdnLogListRequest)
                .SendAsJsonAsync(QiniuJsonSerializerContext.Default.CdnLogListResult);
            return result ?? new CdnLogListResult();
        }
    }
}